//========================变量定义===============================
/**
 * modules引入
 */
var express = require('express'),
	sio = require('socket.io'),
	fs=require('fs'),
	path = require('path'),
	url = require('url'),
	cookie = require('cookie'),
	connect = require('connect'),
	parseCookie = require('connect').utils.parseCookie,
	MemoryStore = connect.middleware.session.MemoryStore;
var storeMemory = new MemoryStore({
	reapInterval: 60000 * 10
});
var MyMongo = require('./server-script/mongodb.js').MyMongo;
var Robot = require('./server-script/robot.js').Robot;
var db = new MyMongo('localhost', 27017, 'bett');
var robot = new Robot();
var globalData = {maxBetId:0, totalBetCount:0, totalBetQty:0.00000000, bankRoll:0.00000000, maxWinQty:0.00000000};
var onlineCount = 0;
//=========================服务配置=============================	
var server = module.export = express.createServer();
server.configure(function(){
	server.use(express.bodyParser());
	server.use(express.cookieParser());
	server.use(express.session({
		secret: 'bett$@#$%#%$#!@@',
		store:storeMemory 
	}));
	server.use(express.methodOverride());
	server.use(server.router);
	server.set('views', __dirname + '/page');
	//server.set('view engine', 'jade');
	server.use(express.static(__dirname + '/script'));
});
	
//=========================配置socket.io=========================
var io = sio.listen(server);
io.set('authorization', function (handshakeData, callback){
        if (!handshakeData.headers.cookie){
            return callback('no found cookie', false);
        }
        handshakeData.cookie = connect.utils.parseJSONCookies(cookie.parse(decodeURIComponent(handshakeData.headers.cookie)));
        var connect_sid = handshakeData.cookie['connect.sid'];
        if (connect_sid){
            storeMemory.get(connect_sid, function (error, session){
                if (error){
                    callback(error.message, false);
                }else{
                    handshakeData.session = session;
                    callback(null, true);
                }
            });
        }else{
            callback('error: no session found!');
        }
    });
server.listen(80, function(){
	var addr = server.address();
	console.log('app listening on http://127.0.0.1：' + addr.port);
	db.query("globalData", function(collection){
		collection.findOne({}, function(err, result){
			if(result != null)
				globalData = result;
		});
	});
	
	timerStart(function(){
		var msg = {beiLv:robot.getBeiLv(), betSize:robot.getBetSize(), type:robot.getType()};
		betHandle(null, msg);
	}, 20000);
});
//=========================请求处理区域=============================
server.get('/',function(req, res){
		var realpath = __dirname + '/page/' + url.parse('index1.html').pathname;
		var txt = fs.readFileSync(realpath);
		res.end(txt);
});

server.post('/login_act',function(req,res){
	var name = req.body.accountName;
	var password = req.body.accountNewPassword;
    var session = req.session;
    if(!session){
    	res.end('sorry, session is null!');
    	return;
    }
    var sessionName = session.name;
    if(!sessionName){
    	db.query("user", function(collection){
    		
    		collection.findOne({name:name, password:password}, function(err, user){
    			if(user){
    				session.name = name;
    				user.password = "";
    				res.redirect('/');
    			}else{
    				res.end('sorry, login fail, user not exists!');
    				return;
    			}
    		});
    	});
    	
    }else{
    	res.end('sorry, login fail, have login!');
    	return;
    }
});
server.post('/regist_act',function(req,res){
	var name = req.body.accountName;
	var password = req.body.accountNewPassword;
    if(name == null || name.trim() == "" || name.trim().length < 6){
    	res.end('sorry, check your username!');
    	return;
    }
    if(password == null || password.trim() == "" || password.trim().length < 6){
    	res.end('sorry, check your password!');
    	return;
    }
    db.query("user", function(collection){
    	collection.findOne({name:name}, function(err, user){
    		if(user != null){
				res.end('sorry, name is exists, please change your name to regist!');
			}else{
				var user = {name:name, password:password, secureCode:'abcd', status:1, betCount:0, winBetCount:0, loseBetCount:0, winQty:0, loseQty:0, remainQty:0, frozenQty:0, createTime:new Date()};
		        collection.insert(user, {safe:true}, function(err, result){	
		        req.session.name = name;
		        user.password = "";
		        res.redirect('/');
		     });
			}
    	});
    });
	
});

server.get('/logout',function(req, res){
	if(req.session.name){
		req.session.name = null;
		res.redirect('/');
	}	
});

//==============================socket链接监听=================================//
io.sockets.on('connection', function (socket){

	/******************************总体发送*********************************/
	onlineCount++;
	socket.on('disconnect', function(){
		if(session)
			session = null;
		console.log("you disconnect!");
	});
	var session = socket.handshake.session;
	//console.log("typeof session.name == "undefined")
	if(session && session.name){
		db.query("user", function(collection){
			collection.findOne({name:session.name}, function(err, user){
				socket.emit("user", user);
			});
		});
		db.query("userStatus", function(collection){
			collection.findOne({name:session.name}, function(err, userStatus){
				socket.emit("userStatus", userStatus);
			});
		});
		
		 db.query("bet", function(collection){
			 collection.find({name:session.name}).sort({time:-1}).limit(100).toArray(function(err, bets){
					socket.emit('myBetList', bets);
			 });
		 });
	}
	db.query("bet", function(collection){
		collection.find().sort({time:-1}).limit(100).toArray(function(err, bets){
			socket.emit('initBetList', bets);
		});
	});			
	socket.emit("globalData", globalData);
/****************************投注处理******************************/
	socket.on('bet', function(msg){
		if(!session){
			socket.emit("error", {msg:'sorry, session is null!'});
			return;
		}
		if(!session.name){
			socket.emit("error", {msg:'sorry, not login!'});
			return;
		}
		betHandle(socket, msg);
	});
/****************************提现处理******************************/
	socket.on('cash', function (msg) {
        if(!session){
        	socket.emit("error", {msg:'sorry, session is null!'});
        	return;
        }
        var sessionName = session.name;
        var address = msg.address;
        var qty = msg.qty;
        var cash = {name:sessionName, address:address, cashQty:qty, cashStatus:0, cashTime:new Date()};
        
        db.query("cash", function(collection){
        	collection.insert(cash, function(err, result){
        		//dongjie
        		db.query("user", function(collection){
        			collection.findOne({name:name}, function(err, user){
        				if(err || null == user){
        					socket.emit("error", {msg:'sorry, system error!'});
        					return;
        				}
        				
        				if(user.remainQty < qty){
        					socket.emit("error", {msg:'sorry, your remainQty not enough!'});
        					return;
        				}
        				
        				//TODO 冻结量增加，余量扣减
        				//db.query("user", callback)
        				
        				collection.insert(cash, function(err, result){
        					console.log("insert cash success!");
        					socket.emit("success", {msg:'cash success!'});
        				});
        			});
        		});
        	});
        });
    });
	
/****************************充值处理******************************/
	socket.on('charge', function (msg) {
        console.log('Message Received: ', msg);
        if(!session){
        	socket.emit("error", {msg:'sorry, session is null!'});
        	return;
        }
        var sessionName = session.name;
        
        //address
        var address = msg.address;
        var qty = msg.qty;
        var charge = {name:sessionName, address:address, chargeQty:qty, cashStatus:0, chargeTime:new Date()};
        db.query("charge", function(collection){
        	collection.insert(charge, function(err, result){
				console.log("insert charge success!");
				socket.emit("success", {msg:'charge success!'});
			});
        });
    });
	
	
/****************************聊天处理******************************/
	socket.on('chat', function(msg){
		if(session && session.name){
			io.sockets.emit("chat", {name:session.name, txt:msg.txt});
		}else{
			socket.emit("error", {msg:"请先登录!"});
		}
	});
});


//==============================辅助函数区域=================================//
function rd(n,m){
	 var c = m-n+1;       
	 return Math.floor(Math.random() * c + n); }  
Date.prototype.format = function(format){   
   var o = {   
     "M+" : this.getMonth()+1, //month   
     "d+" : this.getDate(),    //day   
     "h+" : this.getHours(),   //hour   
     "m+" : this.getMinutes(), //minute   
     "s+" : this.getSeconds(), //second   
     "q+" : Math.floor((this.getMonth()+3)/3), //quarter   
     "S" : this.getMilliseconds() //millisecond   
   };   
   if(/(y+)/.test(format)) format=format.replace(RegExp.$1,   
     (this.getFullYear()+"").substr(4 - RegExp.$1.length));   
   for(var k in o)if(new RegExp("("+ k +")").test(format))   
     format = format.replace(RegExp.$1,   
       RegExp.$1.length==1 ? o[k] :    
         ("00"+ o[k]).substr((""+ o[k]).length));   
   return format;   
};

function timerStart(func, delay) {
	var timerID = setInterval(function() {
	if (!func()) {
		clearInterval(timerID);
		var rdd = rd(1000, 10000);
		console.log("random " + rdd + " ms!");
		timerStart(func, rdd);
		};
	}, delay);}
String.prototype.trim = function() {  
	return this.replace(/^\s+/g,"").replace(/\s+$/g,"");  
};
function betHandle(socket, msg){
		console.log("receive msg bet-----------------------------!");
		var session = null;
		var name = null;
		var isRobot = 0;
		if(isNaN(msg.beiLv)){
			if(null != socket){
				socket.emit("error", {msg:'Payout [1.01-99000]!'});
				return;
			}	
		}
		if(isNaN(msg.betSize)){
			if(null != socket){
				socket.emit("error", {msg:'Bet amount [0.0000001-1000]!'});
				return;
			}		
		}
		
		var beiLv = parseFloat(msg.beiLv.toString()).toFixed(8);
		var betSize = parseFloat(msg.betSize.toString()).toFixed(8);
		if(socket == null)isRobot = 1;
		if(socket){
			session = socket.handshake.session;
			if(!session){
				socket.emit("error", {msg:'sorry, session is null!'});
				return;
			}
			if(!session.name){
				socket.emit("error", {msg:'sorry, not login!'});
				return;
			}
			name = session.name;
		}
		
		
		if(beiLv < 1.01 || beiLv > 99000){
			if(null != socket){
				socket.emit("error", {msg:'Payout [1.01-99000]!'});
				return;
			}
		}
		if(betSize < 0.0000001 || betSize > 1000){
			if(null != socket){
				socket.emit("error", {msg:'Bet amount [0.0000001-1000]!'});
				return;
			}
		}

		var jiLv = parseFloat(robot.numDiv(99, beiLv)).toFixed(2);
		var a = robot.numSub(beiLv, 1);
		var earn = robot.numMulti(a, betSize);
		if(earn == 0 && isRobot)return;
		var lose = betSize;
		var da = parseFloat(robot.numSub(100, jiLv)).toFixed(2);
		var xiao = jiLv;
		var randomTemp = rd(0, 10000);
		var random = parseFloat(robot.numDiv(randomTemp, 100)).toFixed(2);
		var condition = null;
		var profit = null;
		var profitData = null;
		var isWin = false;
		db.query("user", function(collection){
			collection.findOne({name:name}, function(err, user){
				if(socket != null){
					if(err || null == user){
						socket.emit("error", {msg:'sorry, system error!' + err + user});
						return;
					}
					
					if(user.remainQty < lose){
						socket.emit("error", {msg:'sorry, your remainQty not enough!'});
						return;
					}
				}
				
				if(msg.type == 0){
					
					if(random < xiao){
							isWin = true;
							condition = "<label style='font-weight:bold;font-size:15px;color:green;'>" + "&lt; " + xiao + "</label>";
					}else{
						condition = "<label style='font-weight:bold;font-size:15px;color:red;'>" + "&lt; " + xiao;
					}
				}else{
					
					if(random > da){
							isWin = true;
							condition = "<label style='font-weight:bold;font-size:15px;color:green;'>" + "&gt; " + da + "</label>";
					}else{
						condition = "<label style='font-weight:bold;font-size:15px;color:red;'>" + "&gt; " + da + "</label>";
					}
				}
				if(isWin){
					profit = "<font color='green'>+"+earn+"</font>";	
					profitData = earn;
					
				}else{
					profit = "<font color='red'>-"+lose+"</font>";	
					profitData = -lose;
				}

				if(name == null){
					//TODO random get string
					name = robot.getName();
				}
				globalData.maxBetId++;
				
				console.log("投注大小：====== " + betSize);
				var obj = {name:name, time:new Date().format("yyyy-MM-dd hh:mm:ss"), bill:globalData.maxBetId, luck:random, jiLv:jiLv, condition:condition, betSize:betSize, beiLv:beiLv, profit:profit, profitData:profitData, isRobot:isRobot};
				var objData = {name:name, time:new Date().format("yyyy-MM-dd hh:mm:ss"), bill:globalData.maxBetId, luck:random, jiLv:jiLv, condition:condition, betSize:betSize, beiLv:beiLv, profit:profit, profitData:profitData, isRobot:isRobot};
				
				db.query("bet", function(collection){
					collection.insert(objData, {safe:true}, function(err, result){
						//console.log("insert success!!!");
						//update user
						db.query("user", function(collection){
								var up = null;
								if(isWin){
									up = {$inc:{betCount:1, winBetCount:1, winQty:parseFloat(earn), remainQty:parseFloat(earn)}};
								}else{
									up = {$inc:{betCount:1, loseBetCount:1, loseQty:parseFloat(lose), remainQty:-parseFloat(lose)}};
								}
								collection.update({name:name}, up, {safe:true}, function(err, result){
									collection.findOne({name:name}, function(err, entity){
										if(null != socket)
											socket.emit("user", entity);
									});
								});
							
							
						});
						//liguobing2008
						db.query("userStatus", function(collection){
							var inc = null;
							if(isWin){
								inc = {$inc:{totalWinQty:parseFloat(earn), totalLoseQty:0, totalEarnQty:parseFloat(earn), totalWagerQty:parseFloat(betSize)}, $set:{isRobot:isRobot}};
							}else{
								inc = {$inc:{totalWinQty:0, totalLoseQty:parseFloat(lose), totalEarnQty:-parseFloat(lose), totalWagerQty:parseFloat(betSize)}, $set:{isRobot:isRobot}};
							}
							collection.update({name:name}, inc, {upsert:true, safe:true}, function(err, result){
								console.log("insert user earn status success!=====>>" + result + ", " + err);
								collection.findOne({name:name}, function(err, entity){
									console.log(entity);
									if(null != socket)
										socket.emit("userStatus", entity);
								});
								
							});
							
						});
						
						globalData.totalBetCount++;
						if(profitData > globalData.maxWinQty)globalData.maxWinQty = profitData;
						console.log(">>>>>>>>>>>>>>>>>>>>>>>totalBetQty:" + globalData.totalBetQty);
						
						globalData.totalBetQty = robot.numAdd(Number(globalData.totalBetQty), betSize);
	
						globalData.bankRoll = 0;
						//obj.bill++;
						//objData.bill++;
						console.log("broadcast bet info-------------------------!" + obj.beiLv);
						io.sockets.emit('bet', obj);
						if(socket)
							socket.emit('myBet', obj);
	
						db.query("globalData", function(collection){
							/*collection.update({}, {$inc:{maxBetId:1, totalBetCount:1, }}, {upsert:true, safe:true}, function(err, result){
								console.log("insert max bet id success!");
							});*/
							collection.update({}, globalData, {upsert:true, safe:true}, function(err, result){
								console.log("insert max bet id success!");
								io.sockets.emit("globalData", globalData);
							});
						});
						
					});
					console.log("save result return!!!!!!!!!!!!!");
				});
				
			});
		});
		
		
}
//===========================